package com.eduardcapell.lopodder.xml;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.eduardcapell.lopodder.beans.Enclosure;
import com.eduardcapell.lopodder.beans.Feed;
import com.eduardcapell.lopodder.beans.FeedElement;
import com.eduardcapell.lopodder.misc.Constants;

public class XMLUtils {

	private XMLUtils() {

	}


	public static final String feedTitle(Document doc) {
		String s = "";

		NodeList items = doc.getElementsByTagName("channel");
		Node node = items.item(0);

		if (node.getNodeType() == Node.ELEMENT_NODE) {
			Element element = (Element) node;
			NodeList titleLst = element.getElementsByTagName("title");
			Element elTitle = (Element) titleLst.item(0);
			NodeList titol = elTitle.getChildNodes();
			s = ((Node) titol.item(0)).getNodeValue();
		}

		return s;
	}



	public static final List<FeedElement> findFeedElements(Feed feed) {
		List<FeedElement> elements = new ArrayList<FeedElement>();

		Document doc = null;

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
		try {
			db = dbf.newDocumentBuilder();
			doc = db.parse(feed.getUrl().toString());
			doc.getDocumentElement().normalize();
		} catch (Exception e) {
			e.printStackTrace();
            // Fatal error, returning empty list.
            return elements;
		}


		NodeList items = doc.getElementsByTagName("item");

		for (int i = 0; i < items.getLength(); i++) {
			Node node = items.item(i);

			if (node.getNodeType() == Node.ELEMENT_NODE) {
				String elementTitle = getElementDetail(node, "title");
				String elementDescription = getElementDetail(node, "description");
				String pubDate = getElementDetail(node, "pubDate");
				List<Enclosure> enclosures = getEnclosures(node);

				Enclosure enclosure = null;
				if (enclosures != null && enclosures.size() > 0) {
					enclosure = enclosures.get(0);

					FeedElement element = new FeedElement();
					element.setName(elementTitle);
					element.setDate(new java.util.Date());
					element.setFeed(feed);
					element.setDescription(elementDescription);
					element.setUrl(enclosure.getUrl());
					element.setContenType(enclosure.getContentType());
					element.setSize(enclosure.getSize());

					DateFormat df = new SimpleDateFormat(Constants.DATETIME_LONG);
					try {
						element.setDate(df.parse(pubDate.trim()));
					} catch (ParseException e) {
						System.out.println("Date not parseable '" + pubDate + "'");
					} catch (Exception e) {
						System.out.println("Error with date: " + e.getMessage());
					}
					
					if (element.getDate() == null) {
						element.setDate(new java.util.Date());
					}

					elements.add(element);
				} else {
					System.out.println("No enclosure.");
				}



			}
		}

		return elements;
	}

	public static final String getElementDetail(Node node, String idElement) {
		Element nodeElement = (Element) node;

		// Get all child elements with name referenced by idElement
		NodeList subElementsList = nodeElement.getElementsByTagName(idElement);

		// We grab the 1st occurence and cast it to "Element"
		Element firstSubElement = (Element) subElementsList.item(0);

		if (firstSubElement == null) {
			return null;
		}
			
		// Get all contents of that subelement
		NodeList subElementContents = firstSubElement.getChildNodes();

		// Obtain detail
		try {
			String subElementDetail = ((Node) subElementContents.item(0)).getNodeValue();
			return subElementDetail;
		} catch (NullPointerException e) {
			System.out.println("No detail found. NULL.");
			return "NO_DETAIL";
		}
	}

	public static final List<Enclosure> getEnclosures(Node node) {
		List<Enclosure> list = new ArrayList<Enclosure>();
		Element nodeElement = (Element) node;
		NodeList enclosures = nodeElement.getElementsByTagName("enclosure");

		if (enclosures != null && enclosures.getLength() > 0) {
			for (int i=0; i < enclosures.getLength(); i++) {
				Element elementEnclosure = (Element) enclosures.item(i);
				String url = elementEnclosure.getAttribute("url");

				long length = 0;
				try {
					length = Long.parseLong(elementEnclosure.getAttribute("length"));
				} catch (Exception e) {
					System.out.println("No length.");
				}

				String contentType = elementEnclosure.getAttribute("type");

				Enclosure enclosure = new Enclosure();
				try {
					enclosure.setUrl(new URL(url));
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
				enclosure.setSize(length);
				enclosure.setContentType(contentType);

				list.add(enclosure);
			}
		}

		return list;
	}
}
